<template>
	<div class="GobangCanvas">
		<canvas id="canvas"></canvas>
	</div>
</template>

<script>
	export default {
		name: 'GobangCanvas',
		props: {
			chessData: {
				type: Object,
				default () {
					return {
						matrix: [],
						label: '初始化棋盘',
						value: 2,
						win: 0,
						over: false,
						notClick: false,
					};
				}
			},
			clickCallback: {
				type: Function,
				default () {
					return () => {};
				}
			},
		},
		data() {
			return {
				checkerBoradWidth: 35,
				lineNums: 15,
				canvas: {},
				ctx: {},
				chessDataMatrixBak: [],
			}
		},
		methods: {
			init() {
				this.chessData.matrix = [];
				for (let i = 0; i < this.lineNums; i++) {
					this.chessData.matrix.push(new Array(this.lineNums).fill(0, 0, this.lineNums));
					this.chessDataMatrixBak.push(new Array(this.lineNums).fill(0, 0, this.lineNums));
				}
				console.log(this.chessData.matrix)
				this.canvas = document.querySelector('#canvas');
				this.canvas.width = this.checkerBoradWidth * (this.lineNums);
				this.canvas.height = this.checkerBoradWidth * (this.lineNums);
				this.ctx = this.canvas.getContext('2d');
			},

			checkerBroadEvent() {
				this.canvas.addEventListener('click', (e) => {
					if (this.chessData.notClick) return;
					const x = e.offsetX;
					const y = e.offsetY;
					let chessX, chessY;
					let width = this.checkerBoradWidth;
					let width2 = width / 2;
					for (let i = 0; i < this.lineNums; i++) {
						if (
							Math.abs(x - i * width - width2) <= width2) {
							chessX = i;
						}
						if (Math.abs(y - i * width - width2) <= width2) {
							chessY = i;
						}
					}
					if (chessX === undefined || chessY === undefined) return;
					if (this.chessData.matrix[chessX][chessY]) return;

					this.setChessValue(chessX, chessY);
					this.clickCallback(this);
				});
			},
			setChessValue(chessX, chessY) {
				let text = this.chessData.value == 1 ? '白棋' : '黑棋';
				this.chessData.notClick = true;
				this.chessData.label = `${text}落子:(${chessY},${chessX})`;
				this.chessData.matrix[chessX][chessY] = this.chessData.value;
				this.updataChess();
				if (this.victory(this.chessData.matrix, chessX, chessY, this.chessData.value)) {
					console.log(text + '获胜 !');
					this.chessData.over = true;
					this.chessData.win = this.chessData.value;
					this.chessData.label = text + '获胜 !';
					// return;
				}
				this.chessData.value = this.chessData.value == 2 ? 1 : 2;
			},
			drawCheckerBroad() {
				this.ctx.beginPath();
				this.ctx.strokeStyle = '#5d5d5d';
				let width = this.checkerBoradWidth;
				let width2 = width / 2;
				for (let i = 0; i < this.lineNums; i++) {
					this.ctx.moveTo(i * width + width2, width2);
					this.ctx.lineTo(
						i * width + width2,
						this.lineNums * width - width2
					);
					this.ctx.moveTo(width2, i * width + width2);
					this.ctx.lineTo(
						this.lineNums * width - width2,
						i * width + width2
					);
				}
				this.ctx.stroke();
			},
			//画棋子
			oneStep(chessX, chessY, value) {
				let width = this.checkerBoradWidth;
				let width2 = width / 2;
				let arcX = chessX * width + width2;
				let arcY = chessY * width + width2;
				this.ctx.beginPath();
				this.ctx.arc(arcX, arcY, width2 - width / 20, 0, 2 * Math.PI);
				//渐变
				let gradient = this.ctx.createRadialGradient(arcX + 2, arcY - 2,
					width2 - width / 20,
					arcX + 2, arcY - 2, 0);
				this.ctx.fillStyle = gradient;
				if (value == 2) {
					gradient.addColorStop(0, '#0a0a0a');
					gradient.addColorStop(1, '#636766');
				} else {
					gradient.addColorStop(0, '#d1d1d1');
					gradient.addColorStop(1, '#f9f9f9');
				}
				this.ctx.fill();
			},
			//销毁棋子
			minusStep(chessX, chessY) {
				let width = this.checkerBoradWidth;
				let width2 = width / 2;
				let arcX = chessX * width + width2;
				let arcY = chessY * width + width2;
				//擦除该圆
				this.ctx.clearRect(arcX - width2, arcY - width2, width, width);
				// 重画该圆周围的格子
				this.ctx.beginPath();
				this.ctx.moveTo(arcX, arcY - width2);
				this.ctx.lineTo(arcX, arcY + width2);
				this.ctx.moveTo(arcX - width2, arcY);
				this.ctx.lineTo(arcX + width2, arcY);
				this.ctx.stroke();
			},
			updataChess() {
				// if (this.chessData.over || this.chessData.win > 0) return;
				let matrix = this.chessData.matrix;
				let matrixBak = this.chessDataMatrixBak;
				console.log('当前棋盘：', matrixBak);
				console.log('更新棋盘：', matrix);
				for (let i = 0; i < this.lineNums; i++) {
					for (let j = 0; j < this.lineNums; j++) {
						if (matrix[i][j] != matrixBak[i][j]) {
							if (matrix[i][j] == 0) {
								this.minusStep(i, j)
							} else if (matrix[i][j] == 1) {
								this.minusStep(i, j)
								this.oneStep(i, j, 1)
							} else if (matrix[i][j] == 2) {
								this.minusStep(i, j)
								this.oneStep(i, j, 2)
							}
						}
					}
				}
				this.chessDataMatrixBak = JSON.parse(JSON.stringify(matrix)); //深拷贝
			},
			victory(matrix, y, x, borw) {
				console.log("sdf", borw)
				let victoryUnits = [
					[-1, -1],
					[-1, 0],
					[1, -1],
					[0, 1],
				];
				const getLineNums = (matrix, direcsx, x, y, borw) => {
					let results = 0;
					for (let i = 0; i < 5; i++) {
						const vicx = x + i * direcsx[0];
						const vicy = y + i * direcsx[1];
						if (
							matrix[vicy] !== undefined &&
							matrix[vicy][vicx] !== undefined &&
							borw == matrix[vicy][vicx]
						) {
							results++;
						} else {
							break;
						}
					}
					console.log(results);
					return results;
				};
				const result = victoryUnits.some((item) => {
					const n1 = getLineNums(matrix, item, x, y, borw);
					const n2 = getLineNums(
						matrix,
						item.map((v) => -v),
						x,
						y,
						borw
					);
					console.log(n1, n2);
					return n1 + n2 - 1 >= 5;
				});
				console.log(result);
				return result;
			}
		},
		mounted() {
			this.init();
			this.drawCheckerBroad();
			this.checkerBroadEvent();
			// setInterval(()=>{
			// 	this.chessData.notClick =  false;
			// 	console.log("子",this.chessData)
			// },8000);
		},
		watch: {
			chessData: {
				handler(newValue) {
					console.log('chessData(watch):', newValue)
					this.updataChess();
				},
				deep: true
			},
		}
	}
</script>

<style scoped>
	canvas {
		/* 可以自己写一个背景颜色来代替以下四行代码 */
		/* background-image: url(./images/20211227092309212.jpg); */
		background-repeat: no-repeat;
		background-size: cover;
		background-position: center;
		display: block;
		/* margin: 20px auto; */
		margin: 20px;
		box-shadow: -2px -2px 2px #EFEFEF, 5px 5px 5px #B9B9B9;
		/* cursor: pointer; */

	}
</style>
